package com.hqbzl.chat.protocol;

import java.io.*;
import java.util.List;

import com.hqbzl.chat.constant.Constants;
import com.hqbzl.chat.utils.Config;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;

/**
 * 线程安全的父类，可以共用 必须和LengthFieldBasedFrameDecoder一起使用
 */
@ChannelHandler.Sharable
@Slf4j
public class MessageCodec extends MessageToMessageCodec<ByteBuf, MessageType> {

    @Override
    public void encode(ChannelHandlerContext ctx, MessageType message, List<Object> list) throws Exception {

        try {
            final Serializer.Algorithm serializer = Config.getSerializer();
            final ByteBuf byteBuf = ctx.alloc().buffer();
            // 1、4字节的魔数
            byteBuf.writeBytes(new byte[]{1, 2, 3, 4});
            // 2、1字节的版本
            byteBuf.writeByte(1);
            // 3、1字节的序列化方式 jdk 0 json 1
            byteBuf.writeByte(serializer.ordinal());
            // 4、1字节的指令类型
            byteBuf.writeByte(message.getMessageType());
            // 5、4字节
            byteBuf.writeInt(message.getSequenceId());
            // 无意义的部分，只为对齐16字节
            byteBuf.writeByte(0xff);
            // 6、获取内容的字节数组

//            final ByteArrayOutputStream bos = new ByteArrayOutputStream();
//            final ObjectOutputStream oos = new ObjectOutputStream(bos);
//            oos.writeObject(message);
//            final byte[] bytes = bos.toByteArray();
            //final byte[] bytes = Serializer.Algorithm.JAVA.serialize(message);
            final byte[] bytes = serializer.serialize(message);
            // 7、长度
            byteBuf.writeInt(bytes.length);
            // 8、写入内容
            byteBuf.writeBytes(bytes);
            list.add(byteBuf);

        } catch (Exception e) {
            log.debug("MessageCodec encode: {}", e.getMessage(), e);
            throw e;
        }
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> list) throws Exception {
        try {
            final int magicNum = byteBuf.readInt();
            final byte version = byteBuf.readByte();
            // 序列化方式
            final byte serlializerType = byteBuf.readByte();
            final byte messageType = byteBuf.readByte();
            final int sequenceId = byteBuf.readInt();
            final byte xx = byteBuf.readByte();
            final int length = byteBuf.readInt();
            final byte[] bytes = new byte[length];
            byteBuf.readBytes(bytes, 0, length);
            //final MessageType mesage = Serializer.Algorithm.JAVA.deserialize(MessageType.class, bytes);
            // 需要实际类型
            //final Serializer.Algorithm algorithm = Serializer.Algorithm.values()[serlializerType];
            // 解码器
            final Serializer.Algorithm serializer = Serializer.Algorithm.values()[serlializerType];
            // json 需要具体的类型
            final Class<?> clazz = Constants.MESSAGE_TYPE_MAP.get((int)messageType);
            final Object mesage = serializer.deserialize(clazz, bytes);
            list.add(mesage);
//            if (serlializerType == 0) {
//                final ByteArrayInputStream ios = new ByteArrayInputStream(bytes);
//                ObjectInputStream ois = new ObjectInputStream(ios);
//                final Object o = ois.readObject();
//                MessageType mesage = (MessageType) o;
//                list.add(mesage);
//                log.debug("{},{},{},{},{},{},{}, obj= {}", magicNum, version, serlializerType, messageType, sequenceId, xx,
//                        length, mesage);
//            }
        } catch (Exception e) {
            log.debug("MessageCodec decode: {}", e.getMessage(), e);
            throw e;
        }
    }
}
